import os
import requests
import chardet
import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter import ttk
import configparser
import platform
import subprocess
from PIL import Image, ImageTk
from openai import OpenAI
# 配置文件路径
CONFIG_FILE = "config.ini"

# 读取配置
def load_config():
    config = configparser.ConfigParser()
    config_data = {"api_key": "", "input_folder": "", "output_folder": "", "encoding": "utf-8", "file_types": [".c", ".h", ".py", ".asm"]}
    if os.path.exists(CONFIG_FILE):
        config.read(CONFIG_FILE)
        if 'DEFAULT' in config:
            config_data["api_key"] = config['DEFAULT'].get('api_key', "")
            config_data["input_folder"] = config['DEFAULT'].get('input_folder', "")
            config_data["output_folder"] = config['DEFAULT'].get('output_folder', "")
            config_data["encoding"] = config['DEFAULT'].get('encoding', "utf-8")
            file_types_str = config['DEFAULT'].get('file_types', ".c,.h,.py,.asm")
            config_data["file_types"] = file_types_str.split(',') if isinstance(file_types_str, str) else file_types_str
    return config_data

# 保存配置
def save_config(api_key, input_folder, output_folder, encoding, file_types):
    config = configparser.ConfigParser()
    config['DEFAULT'] = {
        'api_key': api_key,
        'input_folder': input_folder,
        'output_folder': output_folder,
        'encoding': encoding,
        'file_types': ','.join(file_types)
    }
    with open(CONFIG_FILE, 'w') as configfile:
        config.write(configfile)

# 翻译文本
def translate_text(text, api_key, target_language="zh"):
    api_url = "https://api.wlai.vip/v1/chat/completions"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {api_key}",
    }
    data = {
        "model": "gpt-4o",
        "messages": [
            {"role": "system", "content": "为代码添加注释"},
            {"role": "user", "content": f"代码中英文翻译成汉语，每行添加汉语注释,，注释率需要超过70%，不更改代码非注释部分，并在最后进行代码总结:\n\n{text}"}
        ]
    }

    
    response = requests.post(api_url, headers=headers, json=data)
    if response.status_code == 200:
        response_data = response.json()
        translated_text = response_data['choices'][0]['message']['content'].strip()
        return translated_text
    else:
        raise Exception(f"请求失败，状态码: {response.status_code}\n响应内容: {response.text}")

    # client = OpenAI(
    #     base_url="https://api.wlai.vip/v1",
    #     api_key = api_key
    # )

    # response = client.chat.completions.create(
    #     model="gpt-4o",
    #     messages=[
    #         {"role": "user", "content": f"代码中英文翻译成汉语，每行添加汉语注释,，注释率需要超过70%，不更改代码非注释部分，并在最后进行代码总结:\n\n{text}"},
    #     ])    
    # response_data = response.json()
    # print(type(response_data))  # <class 'dict'>
    # translated_text = response_data['choices'][0]['message']['content']
    
    # return translated_text

# 检测文件编码
def detect_encoding(file_path):
    with open(file_path, 'rb') as file:
        raw_data = file.read()
        result = chardet.detect(raw_data)
        return result['encoding']

# 添加中文注释
def add_chinese_comments(input_file, output_file, api_key, encoding, batch_size=999):
    try:
        file_encoding = detect_encoding(input_file)
        print(f"检测到的编码: {file_encoding}")

        with open(input_file, 'r', encoding=file_encoding, errors='ignore') as file:
            lines = file.readlines()

        total_lines = len(lines)
        total_batches = (total_lines + batch_size - 1) // batch_size
        batch_count = 0

        translated_content_summary = ""

        for i in range(0, total_lines, batch_size):
            batch_lines = lines[i:i + batch_size]
            content = "".join(batch_lines)

            translated_content = translate_text(content, api_key)
            if not translated_content:
                raise Exception("翻译失败")

            print(f"翻译后的内容 (批次 {batch_count + 1}):")
            print(translated_content)

            translated_lines = translated_content.split('\n')

            # 分隔成三部分
            parts = translated_content.split("```")
            if len(parts) < 3:
                raise Exception("翻译内容格式不正确")

            code_part1 = parts[0].strip()
            summary_part = parts[1].strip()
            code_part2 = parts[2].strip()

            # 写入翻译后的代码部分1
            with open(output_file, 'a', encoding=encoding, errors='ignore') as file:
                file.write(summary_part)
                file.write("\n")

            # 累积总结内容
            translated_content_summary += code_part2 + "\n"

            batch_count += 1
            print(f"转换进度: {batch_count}/{total_batches} 批次完成")

        print(f"处理文件: {os.path.basename(input_file)} 总批次: {total_batches}")

        # 写入总结文件
        with open(os.path.join(os.path.dirname(output_file), "总结文件.txt"), 'a', encoding=encoding, errors='ignore') as summary_file:
            summary_file.write(f"文件: {os.path.basename(input_file)} 的总结:\n")
            summary_file.write(translated_content_summary)
            summary_file.write("\n\n")


    except Exception as e:
        error_message = f"文件 {input_file} 转换失败: {str(e)}\n"
        print(error_message)
        error_log.insert(tk.END, error_message)
        error_log.see(tk.END)

# 处理文件
def process_files(input_folder, output_folder, api_key, encoding, file_types, root):
    total_files = 0
    total_size = 0
    for root_dir, dirs, files in os.walk(input_folder):
        for filename in files:
            if any(filename.endswith(ft) for ft in file_types):
                total_files += 1
                total_size += os.path.getsize(os.path.join(root_dir, filename))

    processed_files = 0
    for root_dir, dirs, files in os.walk(input_folder):
        for filename in files:
            if any(filename.endswith(ft) for ft in file_types):
                input_file_path = os.path.join(root_dir, filename)
                # 构建对应的输出路径
                relative_path = os.path.relpath(root_dir, input_folder)
                output_dir = os.path.join(output_folder, relative_path)
                if not os.path.exists(output_dir):
                    os.makedirs(output_dir)
                output_file_path = os.path.join(output_dir, filename)

                # 更新进度信息
                current_file.set(f"当前处理文件: {input_file_path}")
                progress.set(f"进度: {processed_files + 1}/{total_files} 文件")
                root.update_idletasks()
                root.update()

                add_chinese_comments(input_file_path, output_file_path, api_key, encoding)
                processed_files += 1

# 选择输入文件夹
def select_input_folder():
    folder_selected = filedialog.askdirectory()
    input_folder_path.set(folder_selected)
    update_total_size()

# 选择输出文件夹
def select_output_folder():
    folder_selected = filedialog.askdirectory()
    output_folder_path.set(folder_selected)

# 更新总大小显示
def update_total_size():
    total_size = 0
    for root_dir, dirs, files in os.walk(input_folder_path.get()):
        for filename in files:
            if any(filename.endswith(ft) for ft in selected_file_types()):
                total_size += os.path.getsize(os.path.join(root_dir, filename))
    total_size_var.set(f"总大小: {total_size/1000:.2f} kb,预计花费：{total_size/1000*0.01:.2f} 元 " )

# 获取选中的文件类型
def selected_file_types():
    return [ft for ft, var in file_type_vars.items() if var.get()]

# 打开输出文件夹
def open_output_folder():
    output_folder = output_folder_path.get()
    if platform.system() == "Windows":
        os.startfile(output_folder)
    elif platform.system() == "Darwin":
        subprocess.Popen(["open", output_folder])
    else:
        subprocess.Popen(["xdg-open", output_folder])

# 开始处理
def run_process():
    input_folder = input_folder_path.get()
    output_folder = output_folder_path.get()
    api_key = api_key_entry.get()
    encoding = encoding_var.get()
    file_types = selected_file_types()

    if not input_folder or not output_folder or not api_key:
        messagebox.showwarning("输入错误", "请输入有效的文件夹路径和API Key")
        return

    save_config(api_key, input_folder, output_folder, encoding, file_types)
    error_log.delete(1.0, tk.END)  # 清空错误日志
    process_files(input_folder, output_folder, api_key, encoding, file_types, root)
    messagebox.showinfo("完成", "文件处理完成！")

# 创建主窗口
root = tk.Tk()
root.title("代码注释翻译工具")
root.geometry("700x700")
root.resizable(False, False)

# 加载背景图像
background_image = Image.open("back.jpg")
background_photo = ImageTk.PhotoImage(background_image)

# 创建Canvas以显示背景图像
canvas = tk.Canvas(root, width=700, height=700)
canvas.pack(fill="both", expand=True)
canvas.create_image(0, 0, image=background_photo, anchor="nw")

# 读取配置
config_data = load_config()

# 输入文件夹选择
input_folder_path = tk.StringVar(value=config_data["input_folder"])
output_folder_path = tk.StringVar(value=config_data["output_folder"])
current_file = tk.StringVar()
progress = tk.StringVar()
total_size_var = tk.StringVar()
encoding_var = tk.StringVar(value=config_data["encoding"])

# 创建主框架并设置背景颜色为半透明
main_frame = tk.Frame(root, bg='#F0F0F0', bd=2, relief='solid')
main_frame.place(relx=0.5, rely=0.3, anchor="center")

# 添加所有小部件
tk.Label(main_frame, text="选择输入文件夹:", bg='#F0F0F0').grid(row=0, column=0, padx=5, pady=5, sticky=tk.W)
tk.Entry(main_frame, textvariable=input_folder_path, width=50).grid(row=0, column=1, padx=5, pady=5)
tk.Button(main_frame, text="浏览", command=select_input_folder).grid(row=0, column=2, padx=5, pady=5)

tk.Label(main_frame, text="选择输出文件夹:", bg='#F0F0F0').grid(row=1, column=0, padx=5, pady=5, sticky=tk.W)
tk.Entry(main_frame, textvariable=output_folder_path, width=50).grid(row=1, column=1, padx=5, pady=5)
tk.Button(main_frame, text="浏览", command=select_output_folder).grid(row=1, column=2, padx=5, pady=5)

tk.Label(main_frame, text="输入API Key:", bg='#F0F0F0').grid(row=2, column=0, padx=5, pady=5, sticky=tk.W)
api_key_entry = tk.Entry(main_frame, width=50, bg='#FFFFFF')
api_key_entry.grid(row=2, column=1, padx=5, pady=5)
api_key_entry.insert(0, config_data["api_key"])

tk.Label(main_frame, text="选择输出文件编码:", bg='#F0F0F0').grid(row=3, column=0, padx=5, pady=5, sticky=tk.W)
encoding_options = ["utf-8", "gbk"]
encoding_menu = ttk.OptionMenu(main_frame, encoding_var, *encoding_options)
encoding_menu.grid(row=3, column=1, padx=5, pady=5)

tk.Label(main_frame, text="选择处理文件类型:", bg='#F0F0F0').grid(row=4, column=0, padx=5, pady=5, sticky=tk.W)
file_types = [".c", ".h", ".py", ".asm"]
file_type_vars = {ft: tk.BooleanVar(value=ft in config_data["file_types"]) for ft in file_types}

# 重新排列复选框，使其紧凑
checkbox_frame = tk.Frame(main_frame, bg='#F0F0F0')
checkbox_frame.grid(row=4, column=1, columnspan=2, sticky=tk.W)
for i, ft in enumerate(file_types):
    tk.Checkbutton(checkbox_frame, text=ft, variable=file_type_vars[ft], bg='#F0F0F0', command=update_total_size).grid(row=0, column=i, padx=2, pady=2, sticky=tk.W)

tk.Label(main_frame, textvariable=current_file, bg='#F0F0F0').grid(row=5, column=0, columnspan=3, padx=5, pady=5)
tk.Label(main_frame, textvariable=progress, bg='#F0F0F0').grid(row=6, column=0, columnspan=3, padx=5, pady=5)
tk.Label(main_frame, textvariable=total_size_var, bg='#F0F0F0').grid(row=7, column=0, columnspan=3, padx=5, pady=5)

tk.Button(main_frame, text="开始处理", command=run_process, width=20).grid(row=8, column=0, columnspan=2, padx=5, pady=10)
tk.Button(main_frame, text="打开输出文件夹", command=open_output_folder, width=20).grid(row=8, column=2, padx=5, pady=10)

# 错误日志框架
error_frame = tk.Frame(root, bg='#F0F0F0', bd=2, relief='solid')
error_frame.place(relx=0.5, rely=0.85, anchor="center")
tk.Label(error_frame, text="错误日志:", bg='#F0F0F0').grid(row=0, column=0, sticky=tk.W)
error_log = tk.Text(error_frame, height=10, wrap=tk.WORD, bg='#FFFFFF')
error_log.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
error_log_scroll = ttk.Scrollbar(error_frame, orient=tk.VERTICAL, command=error_log.yview)
error_log['yscrollcommand'] = error_log_scroll.set
error_log_scroll.grid(row=1, column=1, sticky=(tk.N, tk.S))

# 启动时更新文件大小
update_total_size()

# 运行主循环
root.mainloop()
